package com.hjx.movie.core.system.service.admin.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hjx.movie.common.utils.ResultType;
import com.hjx.movie.common.utils.exceptions.CustomException;
import com.hjx.movie.common.utils.tree.TreeBuilder;
import com.hjx.movie.core.system.service.admin.IAreaService;
import com.hjx.movie.core.system.vo.AreaTreeNode;
import com.hjx.movie.persistence.system.mapper.IvyAreaMapper;
import com.hjx.movie.persistence.system.model.IvyArea;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>Title:</p>
 * <p>Description:</p>
 *
 * @author hjx
 * @date 2021/1/30 - 16:35
 */
@Slf4j
@Service
@Transactional
@CacheConfig(cacheNames = "IvyMovie:SpringCache:AreaCache",keyGenerator = "cacheKeyGenerator")
public class AreaService extends ServiceImpl<IvyAreaMapper, IvyArea> implements IAreaService {

    @Cacheable(unless = "#result==null")
    @Override
    public List<AreaTreeNode> findAreaTree(Long rootAreaId,String areaNameLike,Boolean areaStatus) {
        List<IvyArea> areas = getBaseMapper().findAreaTree(rootAreaId, areaNameLike, areaStatus);
        List<AreaTreeNode> areaTreeNodeList = areas.stream().map(item->{
            AreaTreeNode areaTreeNode = new AreaTreeNode();
            BeanUtils.copyProperties(item,areaTreeNode);
            return areaTreeNode;
        }).collect(Collectors.toList());
        if(StringUtils.isNotBlank(areaNameLike)||areaStatus!=null){
            return areaTreeNodeList;
        }else {
            return TreeBuilder.builderTreeWidth(areaTreeNodeList,rootAreaId);
        }
    }

    @Cacheable(unless = "#result==null")
    @Override
    public List<IvyArea> findAreaByPid(Long areaPid) {
        return list(new QueryWrapper<IvyArea>().eq("area_pid",areaPid));
    }

    @CacheEvict(value = "IvyMovie:SpringCache:AreaCache",allEntries = true,beforeInvocation = true )
    @Override
    public boolean addArea(IvyArea area) {
        IvyArea parent = getById(area.getAreaPid());
        Assert.notNull(parent,"找不到此父节点");
        // 将父节点设置为非叶子节点
        parent.setIsLeaf(false);
        area.setIsLeaf(true);
        // 设置层级
        area.setLevel(parent.getLevel()+1);
        // 设置所有的"父节点"信息
        area.setAreaPids(parent.getAreaPids()+",["+area.getAreaPid()+"]");
        area.setStatus(area.getStatus() == null || area.getStatus());
        if (this.updateById(parent)&& this.save(area)){
            log.debug("新增地域成功:{}",area);
            return true;
        }else {
            throw new CustomException(ResultType.USER_INPUT_ERROR,"新增地域失败");
        }
    }

    @CacheEvict(value = "IvyMovie:SpringCache:AreaCache",allEntries = true,beforeInvocation = true )
    @Override
    public boolean deleteArea(Long areaId) {
        // 查询出要删除的节点信息
        IvyArea area = getById(areaId);
        Assert.notNull(area,"查询不到需要删除的接口信息");
        Assert.notNull(area.getAreaPid(),"父节点字段不能为空");

        // 判断自己是不是父节点
        if (!area.getIsLeaf()){
            throw new CustomException(ResultType.USER_INPUT_ERROR,"不能删除有子地域的父级地域");
        }
        // 查询父节点有几个子节点
        QueryWrapper<IvyArea> wrapper = new QueryWrapper<>();
        List<IvyArea> fatherChildren = list(wrapper.like("area_pids","["+area.getAreaPid()+"]"));
        if (fatherChildren.size()==1){
            IvyArea parent = IvyArea.builder().areaId(area.getAreaPid()).isLeaf(true).build();
             if(removeById(areaId)&&updateById(parent)){
                 log.debug("删除地域成功,父级别地域:{}修改为叶子,被删除的地域信息为:{}",area.getAreaPid(),area);
                 return true;
             }
        }else {
            if (removeById(areaId)){
                log.debug("删除地域成功,被删除的地域信息为:{}",area);
                return true;
            }
        }
        throw new CustomException(ResultType.USER_INPUT_ERROR,"删除地域失败");
    }

    @CacheEvict(value = "IvyMovie:SpringCache:AreaCache",allEntries = true,beforeInvocation = true )
    @Override
    public boolean updateArea(IvyArea area) {
        return updateById(area);
    }
}
